home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-10-09 | 30.4 KB | 939 lines | [TEXT/ttxt] |
-
- This document is a technical addendum to the release notes
- included with MacApp 3.0.1 and will be periodically
- updated. The latest version of this document can be found on
- AppleLink at the following path:
- Developer Support:
- Developer Talk:
- Macintosh Development Tool Discussions:
- MacApp Discussion:
- MacApp Technical Updates:
- Note that the MacApp AppleLink discussion archives, included
- with ETO, are an excellent additional source of MacApp
- programming information.
-
- What's New or Changed:
- 10/9/92:
- Section I: #2 changed. #3, #4, #5, #6 new.
- Section II A: #3 changed.
- Section II B: #2 changed. #3, #4, #5 new.
- Section II C: #1 new.
- Section II D: #1, #2, #3, #4 new.
- Section II E: #1 new.
- Section II F: #1, #2, #3, #4, #5 new.
-
- 8/19/92: All new.
-
- =================================================
- Table of Contents:
- I Issues
- 1. Building MacApp 3.0.1 without a Pascal compiler.
- 2. Problems with the MPW 3.2.3 C compiler.
- 3. Using CatchFailures from Pascal.
- 4. C compiler -opt nocse.
- 5. ViewPromoter sometimes fails to promote views.
- 6. Issues when using ResEdit to create menus for use
- in TPopups.
- II Bugs (by Subject)
- A. SUB: Build Problems.
- 1. INITLINKERSYMBOLS offset out of range link
- error with model far builds.
- 2. ViewPromoter malfunction without recompiling.
- 3. Problem Rezing MacApp.r with MPW 3.2.3 and
- later Interfaces.
- B. SUB: View Problems.
- 1. Problem with displaying dialogs, especially
- if created with ViewEdit.
- 2. Problem with QuickTime movie controllers.
- 3. IsGhostWindow and IsSystemWindow should be
- resident.
- 4. Problems with failures when reading 'View'
- resources.
- 5. TTEView miscalculates the page break if the
- last character is a carriage-return.
- C. SUB: Printing Problems.
- 1. Potential problems with non-standard page
- sizes or very large line heights.
- D. SUB: Menu Problems.
- 1. Problems with having MENU and CMNU resources
- with the same ID's.
- 2. Problems with multiple menus with the same
- command number.
- 3. ViewEdit Popups with "Use AddResMenu"
- checked.
- 4. TPopup::SetPopup malfunctions when called
- from applications.
- E. SUB: Internationalization Problems.
- 1. Problem in TKeySelectionBehavior.
- F. SUB: Other Problems.
- 1. Bug in TTabber::Tab.
- 2. Problem with TStream::WriteHandle and NULL
- handles.
- 3. Problems MacApp applications sending
- AppleEvents to themselves.
- 4. IsHandle function not compiled as universal
- code.
- 5. Failure handling bug in TApplication::PostAnEvent.
-
- =================================================
- I ISSUES:
-
- -----------------------------------------
- 1. Building MacApp 3.0.1 without a Pascal compiler.
-
- To build the MacApp 3.0.1 libraries without the Pascal
- compiler, two files must be modified, "MacApp.lib.MAMake"
- (in the MacApp Libraries folder) and "Basic Definitions" (in
- the MacApp Tools folder).
-
- In the file "MacApp.lib.MAMake" comment out the reference to
- UPascalTool in the LibObjs section at the top of the file
- like this:
-
- LibObjs = ∂
- ...
- "{ObjApp}UView.cp.o" ∂
- "{ObjApp}UViewServer.cp.o" ∂
- "{ObjApp}UWindow.cp.o" ∂
- # "{ObjApp}UPascalTool.p.o" ∂ <--- comment out.
- "{ObjApp}UFailure.a.o" ∂
- "{ObjApp}UMemory.a.o" ∂
-
- Then comment out the dependency list for UPascalTool itself.
- This is near the bottom of the file:
-
- #"{ObjApp}UPascalTool.p.o" ƒ ∂
- # "{SrcApp}UPascalTool.inc1.p" ∂
- # "{MAPInterfaces}UList.p" ∂
- # "{MAPInterfaces}MacAppTypes.p" ∂
- # "{MAPInterfaces}UPascalObject.p" ∂
- # "{MAPInterfaces}UObject.p" ∂
- # "{MAPInterfaces}UAssociation.p" ∂
- # "{MAPInterfaces}UFailure.p" ∂
- # "{MAPInterfaces}UMacAppUtilities.p" ∂
- # "{MAPInterfaces}UGeometry.p" ∂
- # "{MAPInterfaces}UPatch.p" ∂
- # "{MAPInterfaces}UMacAppGlobals.p" ∂
- # "{PInterfaces}Types.p" ∂
- # "{PInterfaces}Memory.p" ∂
- # "{PInterfaces}TextEdit.p" ∂
- # "{PInterfaces}Quickdraw.p" ∂
- # "{PInterfaces}OSUtils.p" ∂
- # "{PInterfaces}Editions.p" ∂
- # "{PInterfaces}Files.p" ∂
- # "{PInterfaces}SegLoad.p" ∂
- # "{PInterfaces}Aliases.p" ∂
- # "{PInterfaces}Dialogs.p" ∂
- # "{PInterfaces}Windows.p" ∂
- # "{PInterfaces}Events.p" ∂
- # "{PInterfaces}Controls.p" ∂
- # "{PInterfaces}AppleTalk.p" ∂
- # "{PInterfaces}Notification.p" ∂
- # "{PInterfaces}AppleEvents.p" ∂
- # "{PInterfaces}EPPC.p" ∂
- # "{PInterfaces}PPCToolbox.p" ∂
- # "{PInterfaces}Processes.p" ∂
- # "{PInterfaces}CursorCtl.p" ∂
- # "{PInterfaces}Signal.p" ∂
- # "{PInterfaces}PasLibIntf.p" ∂
- # "{PInterfaces}IntEnv.p" ∂
- # "{PInterfaces}ErrMgr.p" ∂
- # "{PInterfaces}Packages.p" ∂
- # "{PInterfaces}StandardFile.p" ∂
- # "{PInterfaces}Script.p" ∂
- # "{PInterfaces}Resources.p" ∂
- # "{PInterfaces}Fonts.p"
-
- By doing this the UPascalTool unit will not be built and
- Lib'ed into the MacApp library. The unit UPascalTool is only
- used to build MPW Tools in Pascal using MacApp (the
- MABuildTool is an example of this).
-
- Next modify the file "Basic Definitions" by commenting out
- the three line as shown:
-
- SystemSupport = ∂
- "{Libraries}RunTime.o" ∂
- "{CLibraries}StdCLib.o" ∂
- # "{PLibraries}PasLib.o" <---
-
- NonFPUSANELib = ∂
- "{CLibraries}CSANELib.o" ∂
- # "{PLibraries}SANElib.o" ∂ <---
- "{CLibraries}Math.o" ∂
- "{CLibraries}Complex.o" ∂
- "{CLibraries}CPlusLib.o"
-
- FPUSANELib = ∂
- "{CLibraries}CLib881.o" ∂
- "{CLibraries}CSANELib881.o" ∂
- # "{PLibraries}SANELib881.o" ∂ <---
- "{CLibraries}Math881.o" ∂
- "{CLibraries}Complex881.o" ∂
- "{CLibraries}CPlusLib881.o"
-
- Doing this will allow you to build without having Pascal
- installed in your MPW.
-
- One other note, the CPlusExamples will not build because the
- variables {MacAppIntf} and {BuildingBlocksIntf} are used in
- their MAMake files. These variables are defined in Basic
- Definitions by the following lines:
-
- # Leave in for compatibility (2.0)
- MacAppIntf = {MacAppPascalIntf}
-
- # Leave in for compatibility (2.0)
- BuildingBlocksIntf = {BuildingBlocksPascalIntf}
-
- If these variables are changed in the MAMake files to the
- following: {MacAppCPlusIntf} and {BuildingBlocksCPlusIntf}
- then the examples will build. The programmer should use
- these variables in their MAMake files also.
- -----------------------------------------
-
- 2. Problems with the MPW 3.2.3 C compiler.
-
- There is a code generation bug in the MPW 3.2.3 C compiler.
- This bug "appears" to effect MacApp only in the inline
- method CString::Delete. This problem causes the default
- titles for new windows to be "Untitled-1>>>". This problem
- is corrected in the MPW 3.2.4 C compiler.
- -----------------------------------------
-
- 3. Using CatchFailures from Pascal.
-
- When using the CatchFailures routine from Object Pascal, you
- must use a failure handler that is a nested procedure. The
- reason for this is that CatchFailures does not check for a
- NIL staticLink (which you will get if the failure handler is
- a global routine). In C++ this is not an issue, because you
- provide the staticLink manually.
-
- -----------------------------------------
-
- 4. C compiler -opt nocse.
-
- The Latest MPW C release notes for E.T.O. #9 and for
- E.T.O. #8 document C compiler problems with erroneous code
- generation that can occur during the compiler's attempted
- optimization of common sub-expressions. The release notes
- advise disabling these specific optimizations using the -opt
- nocse compiler option. Note that the C compiler will
- otherwise default to enabling these optimizations.
-
- For MacApp programs -opt nocse can be automated by creating
- a new file (named something like "Startup˘Nocse" so that it
- executes after "Startup") in the "Startup Items" folder
- containing the following text:
-
- SET MABuildDefaults "{MABuildDefaults} -C '-opt nocse'"
- EXPORT MABuildDefaults
-
- This will avoid C compiler code gen problems with common sub-
- expression elimination.
-
- -----------------------------------------
-
- 5. ViewPromoter sometimes fails to promote views.
-
- ViewPromoter may fail to do some promotions. There are a
- number of things to try if this occurs. The first is to make
- ViewPromoter's memory partition very large. The second, if
- you have ViewPromoter 3.0b3 available from E.T.O. #6, is to
- attempt to use that version instead to do the promotions. It
- should also be given a very large memory partition in order
- to maximize its chances of accomplishing its task. If
- ViewPromoter 3.0b3 does succeed to promote views that failed
- to promote using the current version, then you should
- determine which specific views failed to promote using the
- current version, and use the earlier version of ViewPromoter
- to promote those views only. If neither version will do the
- promotion, please attempt to isolate only those views that
- fail to promote and submit them as a bug report to
- MACAPP.TEST. Note that ViewPromoter does not support custom
- views.
-
- -----------------------------------------
-
- 6. Issues when using ResEdit to create menus for use in
- TPopups.
-
- When using ResEdit to create menus for use in TPopups, you
- must remember to set the menu-ID to match the resource
- ID. You do this with the MENU command: "Edit Menu & MDEF
- ID…".
-
- =================================================
-
- II BUGS (by subject):
-
- A. SUB: Build Problems:
- -----------------------------------------
- 1. INITLINKERSYMBOLS offset out of range link error with
- model far builds.
-
- There is a problem that can prevent successful linking
- when specifying a -modelfar build. The problem is evident
- in the InitLinkerSymbols PROC in UPascalObject.a. It
- contains A5-relative references to SUPERCLASSTABLE,
- CLASSTABLE, and SELECTORPROCTABLE such as
-
- LEA %_SUPERCLASSTABLE, A0
-
- which are later patched like this
-
- LEA *+xxxx,A0
-
- If any of these modules fall farther than 32K away from
- the InitLinkerSymbols instructions that reference them, a
- linker error will occur. If this happens the linker error
- output might appear something like this:
-
- ### While reading file
- "HD:MPW:MacApp:Libraries:.DebugSymFar:MacApp.lib"
- ### Link: INITLINKERSYMBOLS (32712)
- Reference to: %_SELECTORPROCTABLE in file:
- ### Link: Error: PC-relative edit, offset out of range.
- (Error 48)
- INITLINKERSYMBOLS (32712)
- Reference to: %_CLASSTABLE in file:
- ### Link: Error: PC-relative edit, offset out of range.
- (Error 48)
- INITLINKERSYMBOLS (32712)
- Reference to: INITLINKERSYMBOLS in file: ### Link:
- Error: PC-relative edit,
- offset out of range. (Error 48) INITLINKERSYMBOLS (32712)
-
-
-
- The following 3 changes to the UPascalObject.a file in
- the MacApp:Libraries: folder fix this problem.
-
- In the definition of PROC InitLinkerSymbols, find the
- line
- If qModelFarCode then
-
- Following this line are 3 "LEA" instructions and 3
- "MOVE.L" instructions.
- By changing the form of the LEA instructions, they can be
- changed into -model far references, and avoid the 32K
- limit. Make the following 3 changes...
-
- lea %_SUPERCLASSTABLE(A5),A0
- becomes
- lea (%_SUPERCLASSTABLE).L,A0
-
- lea %_CLASSTABLE(A5),A0
- becomes
- lea (%_CLASSTABLE).L,A0
-
- and
-
- lea %_SELECTORPROCTABLE(A5),A0
- becomes
- lea (%_SELECTORPROCTABLE).L,A0
-
- -----------------------------------------
- 2. ViewPromoter malfunction without recompiling.
-
- A problem exists with ViewPromoter 3.0.1. ; you may need
- to recompile it in order to have it execute successfully.
-
- -----------------------------------------
- 3. Problem Rezing MacApp.r with MPW 3.2.3 and later
- Interfaces.
-
- A problem exists building MacApp 3.0.1 with MPW versions
- 3.2.3 or later.
- In the MPW 3.2.3 Types.r interface file, the declaration
- of the 'aedt' resource that had been used exclusively by
- MacApp is no longer present. This resource declaration
- should be, but is not, present in the MacAppTypes.r file.
- To correct this problem, type the 'aedt' resource
- declaration as it appears below in the MacAppTypes.r
- file, at the end before the #endif. An alternate method
- for this correction is to paste the resource there after
- copying it from the Types.r file included with MPW 3.2.
- Here is the resource declaration as it should appear in
- your MacAppTypes.r file:
-
- /*------------------aedt ˘ Apple Events Template --------
- ---------*/
- /* Resource definition used for associating a value with
- an apple event */
- /* This really only useful for general dispatching */
-
- type 'aedt' {
- wide array {
- unsigned longint; /* Event Class */
- unsigned longint; /* Event ID */
- unsigned longint; /* Value */
- };
- };
-
- NOTE: This is fixed for you in MacApp 3.0.1˘ shipped on
- ETO 9 (this is the only change between MacApp 3.0.1 and
- MacApp 3.0.1˘).
-
- =================================================
-
- B. SUB: View Problems:
- -----------------------------------------
- 1. Problem with displaying dialogs, especially if created
- with ViewEdit.
-
- A drawback in ViewEdit 3.0.1 is that it does not provide
- for behaviors and TDialogBehaviors in particular to be
- specified. A work around for TDialogBehaviors is to fix
- the bug in TWindow::PoseModally() that causes what would
- otherwise be the automagic creation of the
- TDialogBehavior not to take effect. If the following
- lines in PoseModally
-
- TDialogBehavior* itsDialogBehavior = this-
- >GetDialogBehavior();
- IDType result = kNoIdentifier;
- this->Open();
- this->Select();
-
- are changed to
-
- TDialogBehavior* itsDialogBehavior;
- IDType result = kNoIdentifier;
- this->Open();
- this->Select();
- itsDialogBehavior = this->GetDialogBehavior();
-
- then the automagically created behavior is correctly
- assigned to the window and functions correctly.
-
- Alternate ways that you can get a behavior into a view
- resource are to
- - DeRez an existing view or create the view with Rez
- initially; then specify a dialog behavior in the Rez text
- format; then re-Rez, or
- - create your TDialogBehavior or entire dialog
- procedurally.
-
- -----------------------------------------
- 2. Problem with QuickTime movie controllers.
-
- Incompatibilities exist between MacApp 3.0.1 and
- QuickTime (1.0) movie controllers. To avoid these
- problems use the forthcoming 1.5 version of QuickTime.
-
- -----------------------------------------
- 3. IsGhostWindow and IsSystemWindow should be resident.
-
- In file "UWindow.cp", the global functions
- "IsGhostWindow" and "IsSystemWindow" should be in segment
- "MAWindowRes" rather than "MAWindowNonRes.
-
- This will avoid a segment load when these functions are
- called from the window manager patch to the trap
- "_ShowHide". The global function "InitUFloatWindow"
- installs "MAShowHide" as a patch to "_ShowHide". The
- global function "MAShowHide" calls MAFrontWindow. The
- global function "MAFrontWindow" calls the two functions
- "IsGhostWindow" and "IsSystemWindow". If a dialog box is
- opened behind MacApp's back, the trap "_ShowHide" is
- triggered which could cause the Segment Loader to crash.
-
- -----------------------------------------
- 4. Problems with failures when reading 'View' resources.
-
- If a failure occurs during the reading in of a 'View' (or
- 'view') resource, then THandleStream::Free will truncate
- the handle. This will guarantee a failure the next time
- the application attempts to read this resource. One
- possible solution is to change the failure handler in
- TViewServer::ReadViewsFromResource like this.
-
- Failure Handler:
-
- else // Recover
- {
- itsViewStream = (TStream
- *)FreeIfObject(itsViewStream);
- firstView = (TView *)FreeIfObject(firstView);
- fi.ReSignal();
- }
-
- Change too:
-
- else // Recover
- {
- ReleaseResource(((THandleStream*)itsViewStream)-
- >fHandle);
-
- itsViewStream = (TStream
- *)FreeIfObject(itsViewStream);
- firstView = (TView *)FreeIfObject(firstView);
- fi.ReSignal();
- }
-
- We are not aware of any side affects cause by this at
- this time.
-
- -----------------------------------------
- 5. TTEView miscalculates the page break if the last
- character is a carriage-return.
-
- TTEView::DoBreakFollowing will calculates the wrong line
- count if the last character is a carriage-return. This
- results in the last page break not appearing until a
- character is added to the last line. The following fix
- was sent in by a developer:
-
- pascal VCoordinate TMyTEView::DoBreakFollowing(VHSelect
- vhs,
- VCoordinate
- previousBreak,
- Boolean&
- automatic)
- {
- VHSelect orthoVhs;
- short possibleLoc;
- TEStyleHandle theStyles;
- LHHandle lhTab;
- short height;
- short lineHeight;
- short lineNo;
- short countLines; // !!! BUG-
- FIX !!!
- TPrintHandler* itsPrintHandler;
-
- orthoVhs = gOrthogonal[vhs];
- automatic = TRUE;
-
- if (itsPrintHandler = this->GetPrintHandler())
- possibleLoc = (short)Min(kMaxCoord, previousBreak
- + itsPrintHandler->fViewPerPage[orthoVhs]); //!!! long-
- >short
-
- // We want to get rid of the on-screen margin
- represented
- // by fMargin when printing, so
- // adjust things so that the portion of the view
- occupied
- // by the screen margin doesn't get printed.
-
- if (previousBreak == 0)
- possibleLoc += (short)fInset[topLeft][orthoVhs];
- if ((fStyleType == kWithStyle) && (vhs == hSel))
- {
- if (fLastPageBreak == previousBreak)
- {
- height = fLastPageBreak;
- lineNo = fLastLine;
- }
- else
- {
- height = (short)fInset[topLeft][orthoVhs];
- lineNo = 0;
- }
-
- theStyles = GetStylHandle(fHTE);
- lhTab = (**theStyles).lhTab;
-
- // !!! BUG-FIX !!!
-
- countLines = (**fHTE).nLines;
- if ((**fHTE).teLength > 0)
- {
- char lastChar =
- (*(**fHTE).hText)[(**fHTE).teLength-1];
- if (lastChar == chReturn)
- countLines++;
- }
-
- while (lineNo < countLines)
- {
- lineHeight = (*lhTab)[lineNo].lhHeight;
- if (height + lineHeight <= possibleLoc)
- height += lineHeight;
- else
- break;
- ++lineNo;
- }
-
- if (lineNo >= countLines)
- possibleLoc = (short)Max(possibleLoc, height);
- else
- possibleLoc = height;
-
- // !!! BUG-FIX !!!
-
- fLastPageBreak = possibleLoc;
- fLastLine = lineNo;
- }
-
- if ((possibleLoc+fInset[topLeft][orthoVhs]) >=
- fSize[orthoVhs])
- return fSize[orthoVhs];
- else
- return possibleLoc;
- } // TMyTEView::DoBreakFollowing
-
- =================================================
- C. SUB: Printing Problems:
- -----------------------------------------
- 1. Potential problems with non-standard page sizes or
- very large line heights.
-
- MacApp applications can hang when the chosen printer has
- a "page height" less than the default (1") margins (such
- as in the case of a label writer). Similar behavior can
- occur if the height of a line exceeds the height of the
- page (such as with a font size of 300, with 400%
- magnification).
-
- =================================================
- D. SUB: Menu Problems:
- -----------------------------------------
- 1. Problems with having a MENU and a CMNU resource with
- the same ID.
-
- If a program has a MENU and a CMNU resource that have the
- same ID's, MacApp may display the wrong menu.
-
- -----------------------------------------
-
- 2. Problems with multiple menus with the same command
- number.
-
- This was a change made to MacApp that broke the ability
- to have multiple menus containing the same command
- numbers (such as having multiple languages). The change
- is in TCmdTable::CommandToMenuItem. The change was put
- in to fix several performance problems related to typing
- and selections in TTEViews. If you need to use this
- feature, a temporary fix is to change the
- TCmdTable::CommandToMenuItem method to the following:
-
- pascal void TCmdTable::CommandToMenuItem(CommandNumber
- theCommand,
- short& menu,
- short& item)
- {
- if (theCommand < 0) // negative commands are mapped not
- table based
- {
- menu = (short)((-theCommand) >> 8);
- item = (short)((-theCommand) & 255);
- }
- else
- {
- // Assume not found
- menu = 0;
- item = 0;
-
- // Search the table linearly.
- for (ArrayIndex i = 1; i <= this->GetSize(); ++i)
- {
- MenuCmdRecordPtr aMenuCmdRecordPtr =
- (MenuCmdRecordPtr)this->ComputeAddress(i);
- if( theCommand == aMenuCmdRecordPtr->theCmdNumber
- )
- {
- menu = aMenuCmdRecordPtr->theMenuNumber;
- item = aMenuCmdRecordPtr->theItemNumber;
-
- // Return the first menu in the menu bar or
- the last menu not in any menu bar
- if( GetMHandle( aMenuCmdRecordPtr-
- >theMenuNumber ) != NULL )
- break;
- }
- }
- }
- } // TCmdTable::CommandToMenuItem
-
- Be aware that this may induce some performance slow downs
- involving TTEViews, and therefore TEditTexts (one example
- is double click selections of words in a TTEView).
-
- -----------------------------------------
-
- 3. ViewEdit Popups with "Use AddResMenu" checked.
-
- It is not possible to have a TPopup created by resource
- and use the AddResMenu-Feature of this class (e.g. a Font-
- Popup used in a Dialog). The problem is that everytime
- the Popup is created, it calls AddResMenu and adds, lets
- say all the FOND-Resource-Names to the menu. Because
- TPopup does not revert the Menu when it is disposed,
- opening the Dialog again has the effect of duplicating
- the Menu-Items (it grows, and grows, and grows… everytime
- you open the dialog). The only workaround currently
- recommended for this problem is to create the popup
- either procedurally using something like
-
- aPopup = new TPopup;
- aPopup->IPopup(...);
-
- or dynamically using something like
-
- fMenuHandle = NewMenu(kDynamicPopup, "Fonts:");
- MAInsertInMenuTable(fMenuHandle, kDynamicPopup);
- .
- .
- .
- TMyApplication::DoSetupMenus()
- {
- .
- .
- .
- // If the Dynamic menu is not in the menubar then insert
- it
- if (GetMHandle((*fMenuHandle)->menuID) == NULL)
- MAInsertMenu(fMenuHandle, (*fMenuHandle)->menuID, -1);
- }
-
- -----------------------------------------
-
- 4. TPopup::SetPopup malfunctions when called from
- applications.
-
- Avoid using TPopup::SetPopup from applications to switch
- the menu associated with a given TPopup. That feature of
- TPopup is really unstable and should not have been
- included in the public interface of the class. The
- problem is that the Popup class is implemented on top of
- System 7's Popup CDEF which maintains private references
- to the menu handle. As with all other "private" data in
- the toolbox the implementation could change with System
- version 7.1, 7.2... and any class would break that
- depended on the "private" data of the Toolbox structures.
-
- It is instead recommend to put multiple TPopup instances
- in your dialog and show only whichever one is appropriate
- given the context of the UI.
-
- =================================================
- E. SUB: Internationalization Problems:
- -----------------------------------------
- 1. Problem in TKeySelectionBehavior.
-
- There is a problem with the way the TKeySelectionBehavior
- does its character masking. It checks to see if the
- character value is in the range:
- "0x21 to 0x7E". This is not valid for many non-english
- systems. Initial investigation indicates that a (at least
- partial) solution would be to change the test to be:
- "greater than 0x20 and not equal to 0x7F". The resulting
- code would look something like this:
-
- pascal void TKeySelectionBehavior::DoKeyUp(TToolboxEvent*
- event)
- {
- if (event->IsOptionKeyPressed() || event-
- >IsControlKeyPressed()
- || event->fCharacter < 0x20 || event->fCharacter
- == 0x7F)
- inherited::DoKeyUp(event);
- else
- fLastKeyUpTime = event->fEventRecord.when;
- } // TKeySelectionBehavior::DoKeyUp
-
- The test in TKeySelectionBehavior::DoKeyEvent also needs
- to be similarly modified.
-
- =================================================
- F. SUB: Other Problems:
- -----------------------------------------
- 1. Bug in TTabber::Tab.
-
- In file "UTabBehaviors.cp", the method TTabber::Tab
- always calls "SetTargetSelection" of the next target even
- if the target refuses to become a target. This could
- happen if the next target's "WillingToResignTarget"
- method has been overridden and returns false. The
- suggested code for TTabber::Tab is:
-
- //-------------------------------------------------------
- ------------
- // TTabber::Tab:
- //-------------------------------------------------------
- ------------
- #pragma segment MATabBehaviorRes
-
- pascal void TTabber::Tab(Boolean tabBackward)
- {
- this->Reset();
-
- this->FindTargets(tabBackward);
- if (fNext == NULL)
- fNext = fFirst;
- if (fNext)
- {
- if ( fNext->BecomeTarget() )
- {
- fNext->SetTargetSelection(kRedraw);
- }
- }
- } // TTabber::Tab
-
- -----------------------------------------
- 2. Problem with TStream::WriteHandle and NULL handles.
-
- In file "UStream.cp", method "TStream::WriteHandle" will
- crash if a NULL is passed as the handle. If
- "WriteHandle" were to handle this case, it would have to
- write something to the stream so that "ReadHandle" would
- recognize this situation and return a NULL. One solution
- would be for "WriteHandle" to write "kMaxLong" as the
- size of the handle and not write a handle. Then
- "ReadHandle" would check for a value of "kMaxLong" as the
- handle size, not read a handle and return NULL. The code
- would look like:
-
- //-------------------------------------------------------
- ------------
- // TStream::WriteHandle:
- //-------------------------------------------------------
- ------------
- #pragma segment MAStreamWrite
-
- pascal void TStream::WriteHandle(const Handle aHandle)
- {
- if ( aHandle )
- {
- // write the size of the handle
- Size itsSize = GetHandleSize(aHandle);
- this->WriteLong(itsSize);
-
- // write the contents of the handle
- SignedByte savedState = HGetState(aHandle);
- HLock(aHandle);
- FailMemError();
- this->WriteBytes(*aHandle, itsSize);
- HSetState(aHandle, savedState);
- {
- else
- this->WriteLong(kMaxLong); // kMaxLong means
- NULL handle
-
- } // TStream::WriteHandle
-
- //-------------------------------------------------------
- ------------
- // TStream::ReadHandle:
- //-------------------------------------------------------
- ------------
- #pragma segment MAStreamRead
-
- pascal Handle TStream::ReadHandle()
- {
- Handle aHandle = NULL;
- VOLATILE(aHandle);
-
- // read the size of the handle in from the stream
- Size itsSize = this->ReadLong();
-
- if ( itsSize != kMaxLong ) // kMaxLong means
- return NULL handle
- {
-
- // read the handle in from the stream
- FailInfo fi;
- if (fi.Try())
- {
- // allocate the handle
- aHandle = NewPermHandle(itsSize);
-
- // lock the handle and read into it from
- the stream
- SignedByte savedState =
- HGetState(aHandle);
- HLock(aHandle);
- FailMemError();
- this->ReadBytes(*aHandle, itsSize);
- HSetState(aHandle, savedState);
-
- fi.Success();
- }
- else // Recover
- {
- aHandle = DisposeIfHandle(aHandle);
- fi.ReSignal();
- }
- }
- return aHandle;
-
- } // TStream::ReadHandle
-
- -----------------------------------------
- 3. Problems MacApp applications sending AppleEvents to
- themselves.
-
- MacApp applications can get stuck waiting for a reply
- from themselves if they send an AppleEvent to themselves.
- This can be a problem for those trying to provide full
- support for AppleScript. For more information on this
- problem, refer to the MacApp3Tech$ archives and the
- October 92 technote from DTS ("Getting in Touch with
- Yourself Via the AppleEvents Manager").
-
- -----------------------------------------
- 4. IsHandle function not compiled as universal code.
-
- The IsHandle function is not compiled as universal code,
- therefore applications built with the -Debug and -
- NeedsMC68020 options will crash on 68000 on launch. The
- fix is to bracket the function (in UMacAppUtilities.cp)
- with:
-
- #pragma push
- #pragma processor 68000
- #pragma segment MAUtilitiesRes
-
- pascal Boolean IsHandle(Handle h)
- {
- ...
- } // IsHandle
-
- #pragma pop
-
- -----------------------------------------
- 5. Failure handling bug in TApplication::PostAnEvent.
-
- There is a problem that can occur in
- TApplication::PostAnEvent if a failure occurred. The
- problem is that in the event of failure by
- TEvent::IsReadyToPost, the Boolean variable "oldPerm"
- would be used by the failure handler in the call to
- PermAllocation, but the variable is not yet set! This
- can often occur in TClientCommand::IsReadyToPost.
-
- The solution is to override the method
- TApplication::PostAnEvent like this:
-
- pascal void TApplication::PostAnEvent(TEvent* event)//
- Override
- {
- Boolean oldPerm;
- VOLATILE(oldPerm);
-
- FailInfo fi;
- if (fi.Try())
- {
- oldPerm = PermAllocation(FALSE);
- if (event->IsReadyToPost())
- {
- fEventList->Insert(event); // inserts event
- }
- PermAllocation(oldPerm);
- fi.Success();
- }
- else
- {
- PermAllocation(oldPerm);
- if (event->ShouldFreeOnCompletion())
- event = (TEvent*)FreeIfObject(event);
- fi.ReSignal();
- }
- } // TApplication::PostAnEvent
-
-